#include "stdafx.h"
#include "BaseHelper.h"
//#include <windows.h>

#ifdef WIN32
#pragma warning(disable:4786)
#endif

#include <algorithm>
#include <map>
#include <vector>
#include "VFS.h"
#include "CPackage.h"
#include "CPkgFile.h"


using namespace std;

static unsigned int string_id(const char *filename)
{
    char buffer[256];
    int i;
    for (i=0;filename[i];i++)
    {
        if (filename[i]>='A' && filename[i]<='Z')
        {
            buffer[i]=filename[i]+'a'-'A';
        }
        else if (filename[i]=='\\')
        {
            buffer[i]='/';
        }
        else
        {
            buffer[i]=filename[i];
        }
    }
    buffer[i]=0;
    return (unsigned int)ArkString2ID(buffer);
}

// std::map<int,CPackage *>& _CPackage_map()
// {
//     static std::map<int,CPackage *> _obj;
//     return _obj;
// }
// 
// std::vector< sole_ptr<CPackage> >& _CPackage_pool()
// {
//     static std::vector< sole_ptr<CPackage> > _obj;
//     return _obj;
// }

bool CPackage::Load( const char *name )
{
//     int id=string_id(name);

     m_iFileCount = LoadHeader(name);
     
     if (m_iFileCount == 0)
     {
         return false;
     }

     return true;
//     CPackage *p=new CPackage();
//  
//      p->_number=p->LoadHeader(name);
//      if (p->_number==0)
//      {
//          delete p;
//          return 0;
//      }
//     return p;
}

CPackage::CPackage()
{
    m_pFileIndex=0;
    m_iFileCount=0;
}

CPackage::~CPackage()
{
    delete[] m_pFileIndex;

    //add by liuxinglogn 2011-5-10
    m_pkgFile.Close();
}


int CPackage::LoadHeader(const char *name)
{
    if (!m_pkgFile.Open(name))
    {
        return 0;
    }
    PakHeader h;
    m_pkgFile.Read(&h,sizeof(h));

//     if (h.id!=0x57444650){ //'WDFP'
//         return 0;
//     }
    m_pkgFile.Seek(h.offset);
    m_pFileIndex=new ChildFileIndex[h.number];
    m_pkgFile.Read(m_pFileIndex,sizeof(ChildFileIndex)*h.number);
    _filename=name;

    return h.number;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          
}

const char * CPackage::Open(const char *filename,int *pos,int *length)const
{
//     using namespace std;
//     ChildFileIndex temp;
//     temp.uid=string_id(filename);
//     ChildFileIndex *result = lower_bound(m_pFileIndex, m_pFileIndex + m_iFileCount, temp);
//     if (result==m_pFileIndex + m_iFileCount || result->uid!=temp.uid)
//         return 0;
//     *pos=result->dataoffset;
//     *length=result->size;
//     return _filename.c_str();
    return "";
}

//---------------------------------------------------------------------------------------
bool CPackage::SearchFile( uint32 nID, ChildFileIndex* pFileIdx )
{
    for (int count = 0;count < m_iFileCount; count++)
    {
        if (m_pFileIndex[count].uid==nID)
        {
            memcpy(pFileIdx,m_pFileIndex+count,sizeof(ChildFileIndex));
            

            return true;
        }
    }

    pFileIdx=NULL;
    return false;

}

//---------------------------------------------------------------------------------------
bool CPackage::GetFileData( uint32 fileOffset,uint32 size, void* pointer )
{
    m_pkgFile.Seek(fileOffset,SEEK_SET);
    int bytes = m_pkgFile.Read(pointer,size);

    return bytes>0?true:false;
}
